﻿//---------------------------------------------------------------------------
// <copyright file="RibbonSplitButton.cs" company="Microsoft Corporation">
//     Copyright (C) Microsoft Corporation.  All rights reserved.
// </copyright>
//---------------------------------------------------------------------------

namespace Microsoft.Windows.Controls.Ribbon
{
    #region Using declarations

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    #endregion

    #region SplitButtonLabelPosition enum

    /// <summary>
    ///   An enum that describes whether the RibbonSplitButton's label should be associated
    ///   with the the 'button' part of the SplitButton, or the 'Menu' part of the SplitButton.
    /// </summary>
    public enum SplitButtonLabelPosition
    {
        /// <summary>
        ///   Indicates that the RibbonSplitButton's label should be associated with the
        ///   'button' part of the SplitButton.
        /// </summary>
        Button,

        /// <summary>
        ///   Indicates that the RibbonSplitButton's label should be associated with the
        ///   'Menu' part of the SplitButton.
        /// </summary>
        Menu,
    }

    #endregion

    /// <summary>
    ///   A SplitButton which implements IRibbonControl so that it can be placed in the Ribbon.
    /// </summary>
    public class RibbonSplitButton : SplitButton, IRibbonControl
    {
        #region Constructors

        /// <summary>
        ///   Initializes static members of the RibbonSplitButton class.  It also registers
        ///   a couple of callbacks, overrides the default style, and allows ToolTips to be
        ///   displayed even if the control is disabled.
        /// </summary>
        static RibbonSplitButton()
        {
            Type ownerType = typeof(RibbonSplitButton);

            DefaultStyleKeyProperty.OverrideMetadata(ownerType, new FrameworkPropertyMetadata(ownerType));
            CommandProperty.OverrideMetadata(ownerType, new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnCommandChanged)));
            ToolTipProperty.OverrideMetadata(ownerType, new FrameworkPropertyMetadata(null, new CoerceValueCallback(CoerceToolTip)));
            ToolTipService.ShowOnDisabledProperty.OverrideMetadata(ownerType, new FrameworkPropertyMetadata(true));
        }

        #endregion

        #region Public Properties

        /// <summary>
        ///   A property indicating the relative position of the RibbonSplitButton's label.
        /// </summary>
        public SplitButtonLabelPosition LabelPosition
        {
            get { return (SplitButtonLabelPosition)GetValue(LabelPositionProperty); }
            set { SetValue(LabelPositionProperty, value); }
        }

        /// <summary>
        ///   Using a DependencyProperty as the backing store for LabelPositionProperty.  This enables animation, styling, binding, etc...
        /// </summary>
        public static readonly DependencyProperty LabelPositionProperty =
                    DependencyProperty.Register(
                            "LabelPosition",
                            typeof(SplitButtonLabelPosition),
                            typeof(RibbonSplitButton),
                            new UIPropertyMetadata(SplitButtonLabelPosition.Button));

        #endregion

        #region Public Methods

        /// <summary>
        ///   If the developer hasn't assigned their own tooltip, Create and attach a new RibbonToolTip.
        /// </summary>
        /// <param name="d">
        ///   The RibbonSplitButton that the ToolTip property exists on.  When the callback is invoked,
        ///   the property system will pass this value.
        /// </param>
        /// <param name="value">The new value of the ToolTip property, prior to any coercion attempt.</param>
        /// <returns>The coerced value of the ToolTip property.</returns>
        public static object CoerceToolTip(DependencyObject d, object value)
        {
            if (value == null)
            {
                RibbonCommand command = ((RibbonSplitButton)d).Command as RibbonCommand;
                if (command != null &&
                    (!string.IsNullOrEmpty(command.ToolTipTitle) || !string.IsNullOrEmpty(command.ToolTipDescription) || command.ToolTipImageSource != null))
                {
                    value = new RibbonToolTip(command);
                }
            }

            return value;
        }

        /// <summary>
        ///   Invoked whenever the control's template is applied, we also update the ToolTip
        ///   here to assure that it won't be displayed when the RibbonSplitButton's drop
        ///   down is bing displayed.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.UpdateToolTip();
        }

        #endregion

        #region Private Methods

        /// <summary>
        ///   If the Command property changes, we need to coerce some RibbonControl
        ///   specific properties to update their 'back-up' values coming from Command.
        /// </summary>
        /// <param name="d">The RibbonSplitButton on which the Command property has changed value.</param>
        /// <param name="e">
        ///   Event data that is issued by any event that tracks changes to the effective value of this property.
        /// </param>
        private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            RibbonSplitButton splitButton = (RibbonSplitButton)d;
            splitButton.UpdateToolTip();
        }

        /// <summary>
        ///   Coerces the value of the ToolTip, and adds a binding to the ToolTips visibility
        ///   property so that it is only visible when the RibbonSplitButton's items
        ///   are not being displayed.
        /// </summary>
        private void UpdateToolTip()
        {
            CoerceValue(ToolTipProperty);

            Binding binding = new Binding("IsSubmenuOpen");
            binding.Source = GetTemplateChild("PART_ITEMSHOST");
            binding.Converter = new RibbonBooleanToVisibilityConverter();

            RibbonToolTip toolTip = ToolTip as RibbonToolTip;
            if (toolTip != null)
            {
                toolTip.SetBinding(RibbonToolTip.VisibilityProperty, binding);
            }
        }
        #endregion

        #region Internal Attached Properties
        
        // TODO : get rid of this property (hooked into the template)
        public static bool GetIsRibbonSplitButtonHighlighted(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsRibbonSplitButtonHighlightedProperty);
        }

        public static void SetIsRibbonSplitButtonHighlighted(DependencyObject obj, bool value)
        {
            obj.SetValue(IsRibbonSplitButtonHighlightedProperty, value);
        }

        public static readonly DependencyProperty IsRibbonSplitButtonHighlightedProperty =
            DependencyProperty.RegisterAttached("IsRibbonSplitButtonHighlighted", typeof(bool), typeof(RibbonSplitButton), new UIPropertyMetadata(false));

        #endregion
    }
}